package cn.remex.contrib.appbeans;

import cn.remex.core.exception.ServiceCode;
import cn.remex.core.util.Assert;
import cn.remex.core.util.JsonHelper;
import cn.remex.core.util.Judgment;
import cn.remex.core.util.StringHelper;
import cn.remex.db.Database;
import cn.remex.db.DbCvo;
import cn.remex.db.rsql.model.Modelable;
import cn.remex.db.rsql.model.ModelableImpl;
import cn.remex.db.sql.Order;
import cn.remex.db.sql.Where;
import cn.remex.mongo.MongoCvo;
import cn.remex.mongo.MongoManager;
import cn.remex.web.service.BsCvo;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import org.bson.Document;

import java.util.List;
import java.util.Map;

public class DataCvo extends BsCvo {
	public<T extends Modelable, ParentType extends Modelable> DbCvo<T, ParentType> obtainDbCvo(){
		Assert.notNull(beanName,ServiceCode.FAIL,"beanName不能为空");
		Class clazz = Database.getSession().obtainModelClass(beanName);
		return obtainDbCvo(clazz);
	}
	public DbCvo<?,?> obtainDbCvo(String sql, Map<String, Object> params){
		return  Database.getSession().createDbCvo(sql,params).executeMethod("SQL");
	}
	public<T extends Modelable, ParentType extends Modelable> DbCvo<T, ParentType> obtainDbCvo(Class<T> modelClass){
		Assert.notNullAndEmpty(modelClass, ServiceCode.RSQL_BEANCLASS_ERROR,"数据库实体对象不存再，请检查类名是否正确，modelClass="+modelClass);
		DbCvo ret = Database.select(modelClass)//.orderBy(t->t.getId(),Sort.ASC)
				;
		if(!Judgment.nullOrBlank(extColumn)){
//			ret.setDataType("bdodoed");
			ret.withExprColumns(extColumn);
		}

		if(!Judgment.nullOrBlank(filters)){
			ret.getFilter().addGroup(JsonHelper.toJavaObject(filters, Where.class));
//			ret.filter(JsonHelper.toJavaObject(filters, Where.class));
		}

		//用于同时支持对象型Filter和字符串型Filter，这两个之间的关系必须是AND，默认就是，否则可能出现权限漏洞。
		if(this.getFilter()!=null){
			if(ret.getFilter()!=null){
				ret.getFilter().addGroup(this.getFilter());
			}else
				ret.filter(this.getFilter());
			this.getFilter().optimize();//优化那些cn %的语句。如有其它的语句，也可列入到optimize方法中、
		}

		//排序
		if(!Judgment.nullOrBlank(this.getSidx()) && !Judgment.nullOrBlank(this.getSord())){
			ret.orderBy(this.getSidx(), this.getSord());
		}
		if(orders!=null && orders.size()>0){
			for(Order order:orders) {
				ret.orderBy(order.getSidx(), order.getSord());
			}
		}

		//检查dbCvo中非sqlColumn来的filter是否添加响应的sqlColumn TODO 这个方式不对，应该用filterBy的机制
//		ret.getFilter().everyRule(c -> ret._getRootColumn().withColumn(c.getField()));

		return  ret.rowCount(this.getRowCount()).page(this.getPagination());//
	}
	public<T extends Modelable> MongoCvo obtainMongoCvo(Class<T> modelClass) {
		return obtainMongoCvo(StringHelper.getClassSimpleName(modelClass));
	}
	public<T extends Modelable> MongoCvo obtainMongoCvo(String modelName){
		MongoCvo mongoCvo = MongoManager._find(modelName);
//		if(!Judgment.nullOrBlank(extColumn)){
////			ret.setDataType("bdodoed");
//			ret.withExprColumns(extColumn);
//		}

//		if(!Judgment.nullOrBlank(filters)){
//			ret.getFilter().addGroup(JsonHelper.toJavaObject(filters, Where.class));
////			ret.filter(JsonHelper.toJavaObject(filters, Where.class));
//		}

		//用于同时支持对象型Filter和字符串型Filter，这两个之间的关系必须是AND，默认就是，否则可能出现权限漏洞。
		if(this.getFilter()!=null){
			this.getFilter().optimize();//优化那些cn %的语句。如有其它的语句，也可列入到optimize方法中、

			mongoCvo.filter(filter);
		}

//		//排序
//		if(!Judgment.nullOrBlank(this.getSidx()) && !Judgment.nullOrBlank(this.getSord())){
//			ret.orderBy(this.getSidx(), this.getSord());
//		}
//		if(orders!=null && orders.size()>0){
//			for(Order order:orders) {
//				ret.orderBy(order.getSidx(), order.getSord());
//			}
//		}

		//检查dbCvo中非sqlColumn来的filter是否添加响应的sqlColumn TODO 这个方式不对，应该用filterBy的机制
//		ret.getFilter().everyRule(c -> ret._getRootColumn().withColumn(c.getField()));

		return mongoCvo.rowCount(this.getRowCount()).page(this.getPagination());//
	}

	private static final long serialVersionUID = -724854943935644108L;
	private String beanName;
	private int rowCount=10;
	private int pagination=1;
	private int pageCount=0;
	private int recordCount=0;
	private String sidx;
	private String sord;
	private List<Order> orders = null;
	private String extColumn;

	private Where filter;
	private String filters;

	public List<Order> getOrders() {
		return orders;
	}

	public void setOrders(List<Order> orders) {
		this.orders = orders;
	}

	public String getExtColumn() {
		return extColumn;
	}

	public void setExtColumn(String extColumn) {
		this.extColumn = extColumn;
	}

	public String getFilters() {
		return filters;
	}

	public void setFilters(String filters) {
		this.filters = filters;
	}

	public String getSidx() {
		return sidx;
	}
	public void setSidx(String sidx) {
		this.sidx = sidx;
	}
	public String getSord() {
		return sord;
	}
	public void setSord(String sord) {
		this.sord = sord;
	}
	public int getRowCount() {
		return rowCount;
	}
	public void setRowCount(int rowCount) {
		this.rowCount = rowCount;
	}
	public int getPagination() {
		return pagination;
	}
	public void setPagination(int pagination) {
		this.pagination = pagination;
	}
	public int getRecordCount() {
		return recordCount;
	}
	public void setRecordCount(int recordCount) {
		this.recordCount = recordCount;
	}
	public int getPageCount() {
		return pageCount;
	}
	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}

	public String getBeanName() {
		return beanName;
	}

	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}

	public Where getFilter() {
		return filter;
	}

	public void setFilter(Where filter) {
		this.filter = filter;
	}
}
